<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 不用递归 -->
    <script>
      const listData = [
        { id: "p1", title: "广东" },
        { id: "p2", title: "四川" },
        { id: "p2-1", pid: "p2", title: "成都" },
        { id: "p1-1", pid: "p1", title: "广州" },
        { id: "p2-2", pid: "p2", title: "德阳" },
        { id: "p2-3", pid: "p2", title: "绵阳" },
        { id: "p2-1-1", pid: "p2-1", title: "高新区" },
      ];

      function listToTree(list) {
        // 1. 定义最终结果集合
        let result = [];
        // 2. 定义一个映射对象来保存如下格式的数据
        // {
        //   "p1": { id: "p1", title: "广东" },
        //   "p2": { id: "p2", title: "四川" },
        //   "p2-1":  { id: "p2-1", pid: "p2", title: "成都" }
        // }
        let map = {};
        for (let item of list) {
          map[item.id] = item;
        }
        console.log("map", map);

        // 2. 再次循环 list
        for (let item of list) {
          if (!item.pid) {
            // 顶层数据，广东与四川, 将这两条数据直接追加到 result 中
            result.push(item);
          } else {
            // 有 pid 的。
            //    1. 使用 pid 作为 key 到 map 对象中找到对应的数据
            //    2. 让它身上追加儿子
            const current = map[item.pid];
            if (current.children) {
              current.children.push(item);
            } else {
              current.children = [item];
            }
          }
        }

        // end. 返回 result
        return result;
      }

      const arr = listToTree(listData);
      console.log(arr);
    </script>
  </body>
</html>
